package com.am.lottery.util

import com.fasterxml.jackson.core.json.JsonReadFeature
import com.fasterxml.jackson.core.type.TypeReference
import com.fasterxml.jackson.databind.DeserializationFeature
import com.fasterxml.jackson.databind.ObjectMapper
import com.fasterxml.jackson.databind.module.SimpleModule
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer
import com.fasterxml.jackson.databind.type.CollectionType
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateDeserializer
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateSerializer
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer
import com.fasterxml.jackson.module.kotlin.KotlinModule
import com.fasterxml.jackson.module.kotlin.jacksonMapperBuilder
import java.math.BigInteger
import java.time.LocalDate
import java.time.LocalDateTime
import java.time.format.DateTimeFormatter

object JsonUtils {
    val objectMapper: ObjectMapper
        get() {
            val simpleModule = SimpleModule()
            simpleModule.addSerializer(BigInteger::class.java, ToStringSerializer.instance)
            simpleModule.addSerializer(Long::class.javaPrimitiveType, ToStringSerializer.instance)
            simpleModule.addSerializer(Long::class.javaObjectType, ToStringSerializer.instance)

            simpleModule.addSerializer(
                LocalDateTime::class.java,
                LocalDateTimeSerializer(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"))
            )
            simpleModule.addSerializer(
                LocalDate::class.java,
                LocalDateSerializer(DateTimeFormatter.ofPattern("yyyy-MM-dd"))
            )

            simpleModule.addDeserializer(
                LocalDateTime::class.java,
                LocalDateTimeDeserializer(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"))
            )
            simpleModule.addDeserializer(
                LocalDate::class.java,
                LocalDateDeserializer(DateTimeFormatter.ofPattern("yyyy-MM-dd"))
            )


            val objectMapper = jacksonMapperBuilder()
                .enable(JsonReadFeature.ALLOW_UNESCAPED_CONTROL_CHARS)
                .build()
            // 忽略前端多传的字段
            objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
            objectMapper.registerModule(simpleModule)
            objectMapper.registerModule(KotlinModule.Builder().build())
            return objectMapper
        }

    fun <T> parseList(json: String, clz: Class<T>): List<T> {
        val javaType: CollectionType = objectMapper.typeFactory.constructCollectionType(MutableList::class.java, clz)
        return objectMapper.readValue(json, javaType)
    }

    fun <T> parseObj(json: String): T {
        val javaType = objectMapper.typeFactory.constructType(object : TypeReference<T>() {})
        return objectMapper.readValue(json, javaType)
    }

    fun toJsonStr(obj: Any): String {
        return objectMapper.writeValueAsString(obj)
    }
}